package com.taocares.sfss.controller;

import com.google.common.base.Strings;
import com.taocares.sfss.dto.FileDTO;
import com.taocares.sfss.dto.FileResourceDTO;
import com.taocares.sfss.exception.SFSSException;
import com.taocares.sfss.service.FileService;

import java.io.*;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.List;
import java.util.UUID;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

@RestController
@RequestMapping({"/space"})
@Api(tags = {"简单文件存储服务"},description = "基本的文件上传和下载")
public class SimpleFileController {

    private FileService fileService;
    private static final String HEADER_ID = "x-sfss-file-id";
    private static final String HEADER_NAME = "x-sfss-file-name";
    private static final String UTF8 = "utf-8";
    @Autowired
    public SimpleFileController(FileService fileService) {
        this.fileService = fileService;
    }

    @PutMapping(value = {""}, consumes = {"*/*"})
    @ApiOperation(value = "上传文件",notes = "文件放置在请求体中，传送文件流")
    public ResponseEntity uploadFile(String name, String type, Long size, Resource resource) throws IOException {
        if (resource == null) {
            resource = new InputStreamResource(new ByteArrayInputStream(new byte[0]));
        }
        if (Strings.isNullOrEmpty(name)) {
            name = UUID.randomUUID().toString().replace("-", "");
        } else {
            name = URLDecoder.decode(name, "utf-8");
        }
        FileDTO fileDTO = fileService.store(resource.getInputStream(), name, type, size.longValue());
        return ((org.springframework.http.ResponseEntity.BodyBuilder) ((org.springframework.http.ResponseEntity.BodyBuilder) ((org.springframework.http.ResponseEntity.BodyBuilder) ResponseEntity.ok().header("x-sfss-file-id", new String[]{
                fileDTO.getId()
        })).header("x-sfss-file-name", new String[]{
                URLEncoder.encode(name, "utf-8")
        })).header("ETag", new String[]{
                fileDTO.getEtag()
        })).body(fileDTO);
    }
    @PostMapping({""})
    @ApiOperation(value = "通过表单上传文件",notes = "文件放置在表单的 file 字段中，作为表单的最后一个参数")
    public ResponseEntity uploadFile(String name, MultipartFile file) throws IOException {
        if (file == null) {
            throw new SFSSException(com.taocares.sfss.exception.SFSSException.ExceptionType.MISSING_PARAM_IN_FORM, "file �ֶβ���Ϊ��");
        }
        if (Strings.isNullOrEmpty(name)) {
            name = file.getOriginalFilename();
            if (Strings.isNullOrEmpty(name)) {
                name = UUID.randomUUID().toString().replace("-", "");
            }
        }
        FileDTO fileDTO = fileService.store(file, name);
        return ((org.springframework.http.ResponseEntity.BodyBuilder) ((org.springframework.http.ResponseEntity.BodyBuilder) ((org.springframework.http.ResponseEntity.BodyBuilder) ResponseEntity.ok().header("x-sfss-file-id", new String[]{
                fileDTO.getId()
        })).header("x-sfss-file-name", new String[]{
                URLEncoder.encode(name, "utf-8")
        })).header("ETag", new String[]{
                fileDTO.getEtag()
        })).body(fileDTO);
    }
    @GetMapping({"/{id}"})
    @ApiOperation(value = "下载文件")
    public ResponseEntity downloadFile(@PathVariable String id, String fileName) throws IOException {
        FileResourceDTO fileDTO = fileService.getFile(id);
        if (Strings.isNullOrEmpty(fileName)) {
            fileName = fileDTO.getOriginalName();
        }
        return ((org.springframework.http.ResponseEntity.BodyBuilder) ((org.springframework.http.ResponseEntity.BodyBuilder) ((org.springframework.http.ResponseEntity.BodyBuilder) ((org.springframework.http.ResponseEntity.BodyBuilder) ((org.springframework.http.ResponseEntity.BodyBuilder) ((org.springframework.http.ResponseEntity.BodyBuilder) ResponseEntity.ok().header("x-sfss-file-id", new String[]{
                fileDTO.getId()
        })).header("x-sfss-file-name", new String[]{
                URLEncoder.encode(fileName, "utf-8")
        })).header("ETag", new String[]{
                fileDTO.getEtag()
        })).header("Content-Type", new String[]{
                fileDTO.getType()
        })).header("Content-Disposition", new String[]{
                (new StringBuilder()).append("attachment; filename=\"").append(URLEncoder.encode(fileName, "utf-8")).append("\"").toString()
        })).header("Content-Length", new String[]{
                String.valueOf(fileDTO.getSize())
        })).body(fileDTO.getResource());
    }
    @GetMapping({"/{id}/info"})
    @ApiOperation(value = "获取文件基本信息")
    public ResponseEntity getFileInfo(@PathVariable String id) throws UnsupportedEncodingException {
        FileDTO fileDTO = fileService.getFileInfo(id);
        return ((org.springframework.http.ResponseEntity.BodyBuilder) ((org.springframework.http.ResponseEntity.BodyBuilder) ((org.springframework.http.ResponseEntity.BodyBuilder) ResponseEntity.ok().header("x-sfss-file-id", new String[]{
                fileDTO.getId()
        })).header("x-sfss-file-name", new String[]{
                URLEncoder.encode(fileDTO.getOriginalName(), "utf-8")
        })).header("ETag", new String[]{
                fileDTO.getEtag()
        })).body(fileDTO);
    }
    @DeleteMapping({"/{id}"})
    @ApiOperation(value = "删除文件")
    public void deleteFile(@PathVariable String id) {
        fileService.delete(id);
    }
    @DeleteMapping({""})
    @ApiOperation(value = "批量删除文件")
    public void deleteMultipleFile(List idList) {
        fileService.delete(idList);
    }
    @GetMapping({"/{id}/preview"})
    @ApiOperation(value = "预览文件",notes = "不弹窗下载文件，而是将文件流传给客户端，由客户端处理")
    public ResponseEntity previewFile(@PathVariable String id) throws UnsupportedEncodingException {
        FileResourceDTO fileDTO = fileService.getFile(id);
        return ((org.springframework.http.ResponseEntity.BodyBuilder) ((org.springframework.http.ResponseEntity.BodyBuilder) ((org.springframework.http.ResponseEntity.BodyBuilder) ((org.springframework.http.ResponseEntity.BodyBuilder) ((org.springframework.http.ResponseEntity.BodyBuilder) ResponseEntity.ok().header("x-sfss-file-id", new String[]{
                fileDTO.getId()
        })).header("x-sfss-file-name", new String[]{
                URLEncoder.encode(fileDTO.getOriginalName(), "utf-8")
        })).header("ETag", new String[]{
                fileDTO.getEtag()
        })).header("Content-Type", new String[]{
                fileDTO.getType()
        })).header("Content-Length", new String[]{
                String.valueOf(fileDTO.getSize())
        })).body(fileDTO.getResource());
    }
    @GetMapping({"/{id}/thumbnail"})
    @ApiOperation(value = "获取文件略缩图",notes = "缩略图会保持原有比例，允许单独设置宽或高。可以指定强制缩放，以使用指定的宽高")
    public ResponseEntity getThumbnail(@PathVariable String id, Integer width, Integer height, Boolean force) throws UnsupportedEncodingException {
        FileResourceDTO fileDTO = fileService.getFile(id, width, height, force);
        return ((org.springframework.http.ResponseEntity.BodyBuilder) ((org.springframework.http.ResponseEntity.BodyBuilder) ((org.springframework.http.ResponseEntity.BodyBuilder) ((org.springframework.http.ResponseEntity.BodyBuilder) ((org.springframework.http.ResponseEntity.BodyBuilder) ResponseEntity.ok().header("x-sfss-file-id", new String[]{
                fileDTO.getId()
        })).header("x-sfss-file-name", new String[]{
                URLEncoder.encode(fileDTO.getOriginalName(), "utf-8")
        })).header("ETag", new String[]{
                fileDTO.getEtag()
        })).header("Content-Type", new String[]{
                fileDTO.getType()
        })).header("Content-Length", new String[]{
                String.valueOf(fileDTO.getSize())
        })).body(fileDTO.getResource());
    }
}
